<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=4.0,minimum-scale=0.1,user-scalable=1"/>
    <title>冰橙GPT - ChatGPT 开源 单页面 无需编码 史上最简好用</title>
    <link href="//unpkg.com/layui@2.9.23/dist/css/layui.css" rel="stylesheet">
    <script src="//unpkg.com/layui@2.9.23/dist/layui.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <script src="https://cdn.staticfile.org/moment.js/2.29.1/moment.min.js"></script>
    <script src="https://cdn.bootcss.com/fetch/2.0.3/fetch.js"></script>
    <script>
        //百度统计代码
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?b2aafc7c030584826f7aa9402ce1880f";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>

    <style>

        body{background: #fff;}
        *{box-sizing: border-box;}
        .cen {text-align: center;}


        .layui-colla-content,
        .layui-colla-content *{font-size: 14px;}
        .layui-colla-content img{max-width:100%}
        .layui-colla-content div{line-height: 30px; font-size: 14px;}
        .layui-nav-item img{width: 30px; height: 30px; border-rAdius: 50%; margin-right: 10px; }
        .layui-nav-item:nth-child(1) a{padding-left:0px;}
        .layui-table, .layui-table-view {margin: 0;}

        .setBox {position: fixed; width: 80%; min-height: 60%; background: #fff; left: 10%; top:10%; border-radius: 10px; overflow: hidden; box-shadow:#999 6px 6px 51px;
            z-index: 9; padding:15px; box-sizing: border-box;}


    </style>



</head>
<body>

<div id="app">

    <div>
        <div>


            <ul class="layui-nav" >
                <li class="layui-nav-item"><a :href="'?times='+Now()"><img src="https://mp-908027cd-0849-4303-ae20-d3bed9830e3a.cdn.bspapp.com/cloudstorage/f2f85168-46b7-467f-8784-e3a8cc40c0bd.jpg"  >冰橙AI</a></li>
                <ul class="layui-nav" style="right:0px; float: right;">

                    <li class="layui-nav-item" style="right:0" @click="showBox=!showBox"><i class="layui-icon layui-icon-slider" ></i> 设置</li>
                    <li class="layui-nav-item"  style="float: right">
                        <a href="javascript:;">    <i class="layui-icon layui-icon-username"></i>我</a>
                        <dl class="layui-nav-child"> <!-- 二级菜单 -->
                            <dd><a href="https://support.qq.com/product/600324" target="_blank">意见</a></dd>
                            <dd><a href="https://apifox.com/apidoc/shared-52fb41cb-0e62-4e34-b06d-f9334d7a0502/api-106414419">接口</a></dd>
                        </dl>
                    </li>
                </ul>
            </ul>


            <div v-if="showBox" class="setBox layui-anim layui-anim-up" >

                <table class="layui-table " lay-skin="nob" lay-even	>
                    <tr>
                        <td>
                            API地址设置：<br>
                            <input type="text" v-model="apiUrl"  class="layui-input">

                            <br>
                            <a class="layui-btn layui-btn-sm" @click="apiUrl='https://yewu.bcwhkj.cn/api/v2.Gptliu/search';alert('已将API地址设为冰橙GPT专用的国内API接口地址,无需科学上网，国内直连，简单快捷，支持流式/非流式')">冰橙GPTAPI地址</a>
                            <a class="layui-btn layui-btn-sm"  @click="apiUrl='https://api.openai.com/v1/chat/completions';alert('已将API地址设为官方接口地址，请确保你本地环境能正常发起请求')">openai官方API地址</a>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            token / key设置：<br>
                            <input type="password" v-model="apiKey"  class="layui-input">
                            <br>
                            <a class="layui-btn layui-btn-sm" @click="openGzH()">获取冰橙GPT专用TOKEN</a>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Model名称：<br>
                            <input type="text" v-model="apiModel"  class="layui-input">
                            <br>
                            <a class="layui-btn layui-btn-sm"  @click="apiModel='gpt-3.5-turbo-1106';">gpt-3.5-turbo-1106</a>
                            <a class="layui-btn layui-btn-sm"  @click="apiModel='gpt-3.5-turbo';">gpt-3.5-turbo</a>
                        </td>
                    </tr>
                    <tr>
                        <td class="cen" style="padding-top: 80px;">
                            <a @click="save()" class="layui-btn layui-btn-danger">保存并返回</a>
                        </td>
                    </tr>
                </table>
            </div>



        </div>




        <table class="layui-table" lay-skin="nob">
        </table>
        <div style="text-align:center; padding-bottom: 15px;display:none;"><img src="https://bcwhkj.cn/static/upload/image/20230224/1677246223210828.png"><Br>微信扫码获取TOKEN
        </div>


        <table class="layui-table">
            <tr  class=" layui-anim-up layui-anim" style="display: none;">
                <td>

                    <div ><pre style="font-size: 15px; line-height: 26px;  word-break:break-all; white-space:pre-wrap; background: #EEF1FA;padding:5px; float: left;   margin-top: 10px;max-width:80%;">我是人工智能，你有什么要问我的吗？  </pre></div>
                </td>
            </tr>
            <tr v-for="item,key in duiLie"  class=" layui-anim-up layui-anim">
                <td>
                    <span style="color: #fff; float: right; background: #2870EA; padding:5px; font-size: 15px;line-height: 26px; max-width:80%; " @click="Info.wen=item.cxtitlecn1 ? item.cxtitlecn1 : item.wen" v-if="item.wen">
                        {{item.cxtitlecn1 ? item.cxtitlecn1 : item.wen}}
                    </span>
                    <div class="layui-clear"></div>
                    <div  @click="Info.wen=item.wen" @click="copy(item.da)">

                        <pre v-if="item.da" style="font-size: 15px; line-height: 26px;  word-break:break-all; white-space:pre-wrap; background: #EEF1FA;padding:5px; float: left;   margin-top: 10px;max-width:80%;">{{item.da}}  </pre>
                    </div>
                    <div class="layui-clear"></div>
                    <table style="width: 100%;" v-if="duiLie.length>1">
                        <tr>
                            <td style="text-align: right;border:0px; padding:  10px 0;">
                                <span v-if="key>0 && item.cxaddtime" > <a @click="history=0; Info.wen=item.wen;  Info.cxtitlecn1=item.cxtitlecn1; tiJiaoWenTi(); history=1;" class="layui-btn layui-btn-normal layui-btn-sm">生成其它答案</a></span>
                                <span style="font-weight:500; color:#999; font-size: 12px;" v-if="item.cxaddtime">[{{item.cxaddtime}}]</span>
                                <span style="font-weight:500; color:#999;font-size: 12px;" v-if="item.hsTime">[{{item.hsTime}} s]</span>

                            </td>
                        </tr>
                    </table>
                    <div v-if="tiWenZhong==true && key==((duiLie.length)-1)">
                        <blockquote class="layui-elem-quote layui-quote-nm">
                            <span style="color: red;">请等候Ai的回复……<span style="font-weight:500; color:#666;" v-if="that.hsTime>0 && key==(duiLie.length-1)">[ {{that.hsTime}} s]</span><br></span>

                            <span  v-if="that.hsTime>0 && key==(duiLie.length-1) && that.hsTime>40"></span>

                        </blockquote>
                    </div>
                    <div v-if="item.time>0">
                        [{{item.time}} 秒后自动重试]
                    </div>
                </td>
            </tr>
        </table>


        <div v-html="dd"></div>
        <div style="height:250px;"></div>



        <table class="layui-table" style="position: fixed;    bottom: 0px;    left: 0px;    width: 100%;margin:0px;">
            <tr>
                <td >
                    <div style="float:left; width: 80%; overflow: hidden;">
                        <input  style="padding-right: 15px;" class="layui-input" type="text" placeholder="输入您的问题" v-model="Info.wen" @keyup.enter="tiJiaoWenTi()">
                    </div>
                    <div style="float:left; width: 20%;  overflow: hidden;">
                        <a @click="tiJiaoWenTi()" style="width: 100%;"  class="layui-btn layui-btn-normal"  >提交</a>
                    </div>
                    <div class="layui-clear"></div>

                </td>
            </tr>
        </table>

    </div>



</div>
<script>


    var that,timer;
    var app = new Vue({
        el: '#app',
        data:{
            apiKey:'', //冰橙GPT个人TOKEN 通过微信访问冰橙GPT官方网址获取 https://yewu.bcwhkj.cn/h5/ 【个人栏目里】
            apiUrl:'https://yewu.bcwhkj.cn/v1/chat/completions',
            apiModel:'gpt-4o-mini', //新模型速度贼快
            Info:{
                wen:'你好',
                cxtitlecn1:'',
            },
            List:[],
            pageCount:''
            ,count:''
            ,search:{
                page:1,
                limit:10,
            },
            showBox:false,
            hsTime:0,
            tiWenZhong:false,
            duiLie:[
                {
                    wen: '',
                    da: '你好,我是冰橙智能AI客服，你有什么想问我的吗？',
                    cxCount: '',
                    time: 0,
                    cxaddtime: '',
                    hsTime: 0
                }
            ],
            curDuiLie:0,
            wenQuWeiList:[],
            lianXu:false,
            KuaiJieList:[],
            history:1,
            dd:'',

        },
        mounted () {
            that = this;
            if(that.getQV('key')){
                that.apiKey=that.getQV('key');
                localStorage.tokenTemp=that.apiKey;
            }
            if(localStorage.tokenTemp){
                that.apiKey=localStorage.tokenTemp;
            }
        },
        methods: {
            save(){
                console.log('保存')
                localStorage.tokenTemp=that.apiKey;
                that.showBox=!that.showBox;
            },

            tiJiaoWenTi(){
                console.log('触发提交问题！');
                if (that.Info.wen) {
                    // 移到页面最下面
                    $("html,body").animate({ scrollTop: "9999999px" }, 1800);

                    that.tiWenZhong = true;
                    that.duiLie.push({
                        wen: that.Info.wen,
                        cxtitlecn1: that.Info.cxtitlecn1,
                        da: '',
                        cxCount: 'loading……',
                        hsTime: 0,
                    });

                    let postD = {
                        keyword: that.Info.wen,
                        cxtitlecn1: that.Info.cxtitlecn1 ? that.Info.cxtitlecn1 : that.Info.wen,
                        token: localStorage.tokenTemp,
                        history: that.history
                    };
                    let lastNo = that.duiLie.length - 1;

                    // 启用连续对话
                    let messages = [
                        { role: 'system', content: '你是一个能干的助手.' }
                    ];

                    // 将之前的对话内容添加到 messages 数组中
                    that.duiLie.forEach((item, index) => {
                        if (index > 0) { // 跳过第一个默认消息
                            messages.push({ role: 'user', content: item.wen });
                            messages.push({ role: 'assistant', content: item.da });
                        }
                    });

                    // 添加当前用户的消息
                    messages.push({ role: 'user', content: that.Info.wen });

                    // 开始计时
                    timers = setInterval(() => { that.hsTime++; }, 1000);

                    // 调用 liuTiJiao 方法
                    that.liuTiJiao(lastNo, messages, 0);
                }
            },

            getQV(variable)//获取get参数
            {

                //获取get参数
                var getV;
                var query = window.location.search.substring(1);
                var vars = query.split("&");
                for (var i=0;i<vars.length;i++) {
                    var pair = vars[i].split("=");
                    if(pair[0] == variable){
                        getV=decodeURI(pair[1]);
                        return decodeURI(pair[1]);
                    }
                }
                return(false);
            },



            liuTiJiao(lastNo, messages, cid){
                that.Info.wen = '';
                var postData = {
                    model: that.apiModel,
                    messages: messages,
                    stream: true
                };

                // 请求前的调试输出
                console.log('=== 接口请求开始 ===');
                console.log('请求URL:', that.apiUrl);
                console.log('请求参数:', postData);
                console.log('请求头:', {
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer ' + that.apiKey
                });

                var headerss = {
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer ' + that.apiKey
                };
                let accumulator = "";

                fetch(that.apiUrl, {
                    method: 'post',
                    headers: headerss,
                    body: JSON.stringify(postData)
                }).then(function (response) {
                    // 请求响应状态输出
                    console.log('=== 接口响应状态 ===');
                    console.log('响应状态:', response.status, response.statusText);

                    let reader = response.body.getReader();
                    let pump = () => {
                        return reader.read().then(({ value, done }) => {
                            if (value) {
                                let s = new TextDecoder('utf-8').decode(value, { stream: true });
                                accumulator += s;

                                // 输出每次收到的数据块
                                console.log('=== 接收数据块 ===');
                                console.log('原始数据:', s);
                            }
                            if (done) {
                                console.log('=== 数据接收完成 ===');
                                console.log('累积数据:', accumulator);
                                that.tiWenZhong = false;
                                return false;
                            }

                            let segments = accumulator.split("data:");
                            for (let i = 0; i < segments.length - 1; i++) {
                                let seg = segments[i].trim();
                                if (!seg) continue;
                                if (seg.includes("[DONE]")) continue;

                                try {
                                    let returnD = JSON.parse(seg);
                                    console.log('=== 解析数据 ===');
                                    console.log('解析结果:', returnD);

                                    if (returnD.choices && returnD.choices[0].delta) {
                                        const delta = returnD.choices[0].delta;

                                        // 确保对话队列存在该条目
                                        if (!that.duiLie[lastNo]) {
                                            that.duiLie[lastNo] = {
                                                wen: that.Info.wen,
                                                da: '',
                                                cxCount: '',
                                                time: 0,
                                                cxaddtime: that.Now(),
                                                hsTime: 0
                                            };
                                        }

                                        // 处理返回内容
                                        if (delta.content !== undefined) {
                                            that.duiLie[lastNo].da += delta.content; // 追加内容
                                            console.log('当前回复内容:', that.duiLie[lastNo].da);

                                            // 确保视图更新
                                            that.$nextTick(() => {
                                                that.$forceUpdate();
                                            });
                                        }
                                    }

                                    // 处理完成标记
                                    if (returnD.choices && returnD.choices[0].finish_reason === 'stop') {
                                        console.log('回复完成');
                                        that.tiWenZhong = false;
                                        that.duiLie[lastNo].hsTime = that.hsTime;
                                        clearInterval(timers); // 停止计时
                                    }

                                } catch (e) {
                                    console.error('数据解析错误:', e, seg);
                                }
                            }
                            accumulator = segments[segments.length - 1];
                            return pump();
                        });
                    };
                    pump();
                }).catch(function (err) {
                    console.error("=== 请求失败 ===");
                    console.error("错误详情:", err);
                    that.tiWenZhong = false; // 确保错误时也重置状态
                });
            },

            
            Now(){
                return moment().get('year')+'-'+
                    (moment().get('month')+1)+'-'+
                    moment().get('date')+' '+
                    moment().get('hour')+':'+
                    moment().get('minute')+':'+
                    moment().get('second');
            },
            
            /**
             * @return 冰橙GPT公众号客服
             */
            openGzH(){
                var index = layer.open({
                    content: '<img src="https://mp-908027cd-0849-4303-ae20-d3bed9830e3a.cdn.bspapp.com/cloudstorage/1dc5e9e2-2da7-4df0-8b6e-bde75b2b131f.jpg" style="height: 300px;" ><br>长按识别二维码，关注公众号进行留言咨询'
                });
            },




        }
    });


</script>
</body>
</html>
</html>